//! # RISC-V CPU 核心模拟模块
//!
//! 这个模块提供了 `Cpu` 结构体，用于模拟一个简化的 RISC-V 处理器。
//! 它的核心职责是管理CPU状态，并执行指令周期。
//!
//! # 主要功能
//!
//! - 包含核心的CPU状态：程序计数器 (PC)、32个通用寄存器和4096个CSR寄存器。
//! - 实现了核心的“取指-译码-执行”指令周期。
//! - 提供 `run()` 方法来完整执行程序，以及 `step()` 方法用于单步调试。
//! - 通过持有的 `Memory` 模块来与内存进行交互。
//! - 需要参考指令实现详见：[isa模块](/src/isa/inst.rs)

use crate::common::SimError;
use crate::mem::Memory;
use crate::isa::{decode, Instruction}; 

/// RISC-V 32个通用寄存器的ABI（应用程序二进制接口）命名。
///
/// 这个枚举主要用于代码中需要明确使用某个特定寄存器名的地方，以提高可读性。
/// 例如，`GRegister::Sp as usize` 可以获取栈指针寄存器的索引。
#[allow(non_camel_case_types)] // 我们暂时保留ABI命名，但推荐使用 UpperCamelCase
#[derive(Debug)]
pub enum GRegister {
    Zero = 0, Ra = 1, Sp = 2, Gp = 3,
    Tp = 4,   T0 = 5, T1 = 6, T2 = 7,
    S0 = 8,   S1 = 9, A0 = 10, A1 = 11,
    A2 = 12,  A3 = 13, A4 = 14, A5 = 15,
    A6 = 16,  A7 = 17, S2 = 18, S3 = 19,
    S4 = 20,  S5 = 21, S6 = 22, S7 = 23,
    S8 = 24,  S9 = 25, S10 = 26, S11 = 27,
    T3 = 28,  T4 = 29, T5 = 30, T6 = 31,
}

// --- RISC-V CSR 地址常量 ---
// 在 RISC-V Unprivileged Spec v2.2 第 20 页可以找到这些地址
pub const CSR_MTVEC: usize = 0x305;
pub const CSR_MEPC:  usize = 0x341;
pub const CSR_MCAUSE: usize = 0x342;
pub const CSR_MTVAL: usize = 0x343;

// --- RISC-V 陷阱原因常量 ---
// 在 RISC-V Unprivileged Spec v2.2 第 40 页可以找到这些原因码
// 我们先定义几个会用到的
pub const CAUSE_ECALL: u32 = 8;
pub const CAUSE_ILLEGAL_INSTRUCTION: u32 = 2;

/// RISC-V CPU 结构体。
///
/// 存储了CPU的所有核心状态，并提供了操作这些状态的方法。
/// 字段默认为私有，以保证状态的封装性和一致性。
pub struct Cpu {
    /// 程序计数器，指示下一条要执行的指令地址。
    pc: u32,
    /// 32个通用寄存器，用于存储运算数据。
    regs: [u32; 32],
    /// 控制和状态寄存器(CSR)，用于存储处理器状态和控制信息。
    csrs: [u32; 4096],
    /// CPU拥有的内存实例，用于与内存进行交互。
    memory: Memory,
}

impl Cpu {
    /// 创建一个新的CPU实例。
    ///
    /// # 参数
    /// * `memory` - 一个 `Memory` 实例，CPU将获得其所有权。
    ///
    /// # 返回值
    /// 返回一个初始化完成的 `Cpu` 实例，其PC指向内存基地址，所有寄存器清零。
    pub fn new(memory: Memory) -> Self {
        Self {
            pc: memory.base,
            regs: [0; 32],
            csrs: [0; 4096],
            memory,
        }
    }

    /// 连续执行指令直到程序结束或发生错误。
    ///
    /// # 返回值
    /// - `Ok(())`: 如果程序正常执行完毕（例如遇到EBREAK）。
    /// - `Err(SimError)`: 如果在执行过程中发生任何错误。
    pub fn run(&mut self) -> Result<(), SimError> {
        loop {
            // step() 现在返回一个 bool 值来指示是否应该继续
            // Ok(true) = 继续, Ok(false) = 停止 (EBREAK)
            if !self.step()? {
                log::info!("EBREAK 指令遇到，模拟器正常停止。");
                break;
            }
        }
        Ok(())
    }

    /// 执行一个完整的指令周期：取指、(译码)、执行。
    ///
    /// # 返回值
    /// - `Ok(())`: 如果指令周期成功完成。
    /// - `Err(SimError)`: 如果在取指或执行过程中发生错误。
    /// 执行单步周期，返回一个 bool 值指示是否应继续执行
    pub fn step(&mut self) -> Result<bool, SimError> {
        // 1. 取指
        let instruction_data = self.fetch()?;
        log::info!(
            "0x{:08x}: 0x{:08x}",
            self.get_pc(),
            instruction_data,
        );

        // 2. 译码
        match decode(instruction_data) {
            Ok(instruction) => {
                // 3. 译码成功，执行指令
                log::debug!("Decoded: {:?}", instruction);
                self.execute(instruction)
            }
            Err(_) => {
                // 译码失败，触发非法指令异常！
                self.trigger_trap(CAUSE_ILLEGAL_INSTRUCTION, instruction_data);
                Ok(true) // 陷阱处理后，我们希望模拟器继续运行（执行陷阱处理程序）
            }
        }
    }

    /// 从内存中获取当前PC指向的指令。
    pub fn fetch(&self) -> Result<u32, SimError> {
        self.memory.read_u32(self.pc)
    }

    /// 执行一条指令并更新CPU状态。
    ///
    /// **注意**: 当前这是一个占位符实现。它只将PC增加4。
    /// 在下一阶段，这里将包含一个巨大的`match`语句来处理所有不同的指令。
    /// 执行一条译码后的指令，并返回一个 bool 值指示是否应继续执行。
    pub fn execute(&mut self, instruction: Instruction) -> Result<bool, SimError> {
        let mut next_pc = self.pc.wrapping_add(4);

        match instruction {
            // RV32I Base Instruction Set

            // Loads
            // 字节加载
            Instruction::LB { rd, rs1, imm } => {
                // 1. 获取基址寄存器 rs1 的值
                let base_addr = self.get_reg(rs1)?;

                // 2. 计算内存地址
                let addr = base_addr.wrapping_add(imm as u32);

                // 3. 从内存读取一个字节 (u8)
                let byte_val = self.memory.read_u8(addr)?;

                // 4. 将 u8 进行符号扩展为 32 位
                //    (u8 as i8) -> i32 (这里发生符号扩展) -> u32
                let extended_val = byte_val as i8 as u32;

                // 5. 使用我们安全的方法将结果写入目标寄存器 rd
                self.set_reg(rd, extended_val)?;
            }
            // 半字加载
            Instruction::LH { rd, rs1, imm } =>{
                let base_addr = self.get_reg(rs1)?;
                let addr: u32 = base_addr.wrapping_add(imm as u32);
                let half_word = self.memory.read_u16(addr)?;
                let extended_val = half_word as i16 as u32;
                self.set_reg(rd, extended_val)?;
            },
            // 字加载
            Instruction::LW { rd, rs1, imm } => {
                let base_addr = self.get_reg(rs1)?;
                let addr: u32 = base_addr.wrapping_add(imm as u32);
                match self.memory.read_u32(addr) {
                    Ok(word) => self.set_reg(rd, word)?,
                    Err(e) => self.handle_memory_error(e, false),
                }
            }
            // 无符号字节加载
            Instruction::LBU { rd, rs1, imm } => {
                let base_addr = self.get_reg(rs1)?;
                let addr = base_addr.wrapping_add(imm as u32);
                let byte_val = self.memory.read_u8(addr)?;

                // 对于 LBU，我们直接将 u8 转换为 u32，高位自动补 0（零扩展）
                let extended_val = byte_val as u32;

                self.set_reg(rd, extended_val)?;
            }
            // 无符号半字加载
            Instruction::LHU { rd, rs1, imm } =>{
                let base_addr = self.get_reg(rs1)?;
                let addr: u32 = base_addr.wrapping_add(imm as u32);
                let half_word = self.memory.read_u16(addr)?;
                let extended_val = half_word as u32;
                self.set_reg(rd, extended_val)?;
            }
            
            // Stores
            // 字节存储
            Instruction::SB { rs1, rs2, imm } => {
                let base_addr = self.get_reg(rs1)?;
                let addr = base_addr.wrapping_add(imm as u32);
                // 从 rs2 寄存器中获取要存储的值
                let store_val = self.get_reg(rs2)?;
                // 将 u32 值截断为 u8 (只取低8位)，然后写入内存
                self.memory.write_u8(addr, store_val as u8)?;
            }
            // 半字存储
            Instruction::SH { rs1, rs2, imm } =>  {
                let base_addr = self.get_reg(rs1)?;
                let addr = base_addr.wrapping_add(imm as u32);
                let store_val = self.get_reg(rs2)?;
                // 将 u32 值截断为 u16 (只取低16位)，然后写入内存
                self.memory.write_u16(addr, store_val as u16)?;
            }
            // 字存储
            Instruction::SW { rs1, rs2, imm } => {
                // TODO: 实现 SW (Store Word)
                // 1. 计算内存地址: `rs1` 的值 + `imm` (符号扩展)
                // 2. 读取 `rs2` 寄存器的值
                // 3. 将 `rs2` 的值写入计算出的内存地址
                let base_addr = self.get_reg(rs1)?;
                let addr = base_addr.wrapping_add(imm as u32);
                let store_val = self.get_reg(rs2)?;
                // 写入完整的 u32 值
                self.memory.write_u32(addr, store_val)?;
            }

            // Shifts
            // 逻辑左移立即数
            Instruction::SLLI { rd, rs1, shamt } => {
                let rs1_val = self.get_reg(rs1)?;
                let result = rs1_val << shamt; // 对 u32 左移
                self.set_reg(rd, result)?;
            }
            // 逻辑右移立即数
            Instruction::SRLI { rd, rs1, shamt } => {
                let rs1_val = self.get_reg(rs1)?;
                let result = rs1_val >> shamt; // 对 u32 右移
                self.set_reg(rd, result)?;
            }
            // 算术右移立即数
            Instruction::SRAI { rd, rs1, shamt } => {
                let rs1_val = self.get_reg(rs1)?;
                let result = (rs1_val as i32 >> shamt) as u32; // 关键：先转为 i32 再右移
                self.set_reg(rd, result)?;
            }
            // 逻辑左移
            Instruction::SLL { rd, rs1, rs2 } => {
                let rs1_val = self.get_reg(rs1)?;
                let rs2_val = self.get_reg(rs2)?;
                let shamt = rs2_val & 0x1F;
                let result = rs1_val << shamt;
                self.set_reg(rd, result)?;
            }
            // 逻辑右移
            Instruction::SRL { rd, rs1, rs2 } =>  {
                let rs1_val = self.get_reg(rs1)?;
                let rs2_val = self.get_reg(rs2)?;
                let shamt = rs2_val & 0x1F;
                let result = rs1_val >> shamt;
                self.set_reg(rd, result)?;
            }
            // 算术右移
            Instruction::SRA { rd, rs1, rs2 } => {
                // 算术右移，需要注意符号位扩展
                // 1. 获取源寄存器的值
                let rs1_val = self.get_reg(rs1)?;
                let rs2_val = self.get_reg(rs2)?;

                // 2. 提取位移量 (与 SLL, SRL 相同)
                let shamt = rs2_val & 0x1F;

                // 3. 关键步骤：
                //    a. 将 rs1_val (u32) 的比特位解释为 i32
                //    b. 对 i32 执行 >> 操作 (自动触发算术右移)
                //    c. 将结果的比特位解释回 u32
                let result = ((rs1_val as i32) >> shamt) as u32;

                // 4. 将结果写回目标寄存器
                self.set_reg(rd, result)?;
            }

            // Arithmetic
            Instruction::ADDI { rd, rs1, imm } => {
                let res = self.get_reg(rs1)?.wrapping_add(imm as u32);
                self.set_reg(rd, res)?;
            }
            // 寄存器运算 加法
            Instruction::ADD { rd, rs1, rs2 } => {
                let res = self.get_reg(rs1)?.wrapping_add(self.get_reg(rs2)?);
                self.set_reg(rd, res)?;
            }
            // 寄存器运算 减法
            Instruction::SUB { rd, rs1, rs2 } => {
                let res = self.get_reg(rs1)?.wrapping_sub(self.get_reg(rs2)?);
                self.set_reg(rd, res)?;
            }
            // 高位立即数加载
            Instruction::LUI { rd, imm } => {
                self.set_reg(rd, imm as u32)?;
            }
            // PC 加立即数
            Instruction::AUIPC { rd, imm } => {
                let offset = (imm as u32) << 12;
                self.set_reg(rd, self.pc.wrapping_add(offset))?;
            }
            
            // Logical
            // 小于立即数则置位
            Instruction::SLTI { rd, rs1, imm } =>  {
                // 1. 获取 rs1 的值 (u32)
                let rs1_val = self.get_reg(rs1)?;
                // 2. 关键：将 rs1_val (u32) 解释为 i32，然后与 imm (i32) 进行有符号比较
                let result = if (rs1_val as i32) < imm {
                    1
                } else {
                    0
                };
                // 3. 将结果 (0 或 1) 写入目标寄存器 rd
                self.set_reg(rd, result)?;
            }
            // 无符号小于立即数则置位
            Instruction::SLTIU { rd, rs1, imm } => {
                let rs1_val = self.get_reg(rs1)?;
                // 关键：将 imm (i32) 解释为 u32，然后与 rs1_val (u32) 进行无符号比较
                let result = if rs1_val < (imm as u32) { 1 } else { 0 };
                 self.set_reg(rd, result)?;
            }
            // 无立即数异或
            Instruction::XORI { rd, rs1, imm } => {
                let rs1_val = self.get_reg(rs1)?; // rs1_val 是 u32
                let result = rs1_val ^ (imm as u32);
                self.set_reg(rd, result)?;
            }
            
            // OR Immediate: 按位或立即数
            // 功能: 将 rs1 寄存器的值与符号扩展后的 imm 进行按位或(OR)，结果写入 rd。
            Instruction::ORI { rd, rs1, imm } => {
                let rs1_val = self.get_reg(rs1)?;
                let result = rs1_val | (imm as u32);
                self.set_reg(rd, result)?;
            }

            // AND Immediate: 按位与立即数
            // 功能: 将 rs1 寄存器的值与符号扩展后的 imm 进行按位与(AND)，结果写入 rd。
            Instruction::ANDI { rd, rs1, imm } => {
                let rs1_val = self.get_reg(rs1)?;
                let result = rs1_val & (imm as u32);
                self.set_reg(rd, result)?;
            }
            
            // --- Logical (Register-Register) ---

            // Set if Less Than (Signed): 有符号小于则置位
            // 功能: 将 rs1 和 rs2 的值作为有符号数进行比较。如果 rs1 < rs2，则向 rd 写入 1，否则写入 0。
            Instruction::SLT { rd, rs1, rs2 } => {
                let rs1_val = self.get_reg(rs1)?;
                let rs2_val = self.get_reg(rs2)?;
                let result = if (rs1_val as i32) < (rs2_val as i32) {
                    1
                } else {
                    0
                };
                self.set_reg(rd, result)?;
            }

            // Set if Less Than (Unsigned): 无符号小于则置位
            // 功能: 将 rs1 和 rs2 的值作为无符号数进行比较。如果 rs1 < rs2，则向 rd 写入 1，否则写入 0。
            Instruction::SLTU { rd, rs1, rs2 } => {
                let rs1_val = self.get_reg(rs1)?;
                let rs2_val = self.get_reg(rs2)?;
                let result = if rs1_val < rs2_val {
                    1
                } else {
                    0
                };
                self.set_reg(rd, result)?;
            }

            // XOR: 按位异或
            // 功能: 将 rs1 和 rs2 寄存器的值进行按位异或(XOR)，结果写入 rd。
            Instruction::XOR { rd, rs1, rs2 } => {
                let rs1_val = self.get_reg(rs1)?;
                let rs2_val = self.get_reg(rs2)?;
                let result = rs1_val ^ rs2_val;
                self.set_reg(rd, result)?;
            }

            // OR: 按位或
            // 功能: 将 rs1 和 rs2 寄存器的值进行按位或(OR)，结果写入 rd。
            Instruction::OR { rd, rs1, rs2 } => {
                let rs1_val = self.get_reg(rs1)?;
                let rs2_val = self.get_reg(rs2)?;
                let result = rs1_val | rs2_val;
                self.set_reg(rd, result)?;
            }
            // AND: 按位与
            // 功能: 将 rs1 和 rs2 寄存器的值进行按位与(AND)，结果写入 rd。
            Instruction::AND { rd, rs1, rs2 } => {
                let res = self.get_reg(rs1)? & self.get_reg(rs2)?;
                self.set_reg(rd, res)?;
            }

            // Branch

            // Branch if Equal: 相等则跳转
            // 功能: 比较两个寄存器的值，如果相等则跳转到指定位置。
            Instruction::BEQ { rs1, rs2, imm } => {
                if self.get_reg(rs1)? == self.get_reg(rs2)? {
                    next_pc = self.pc.wrapping_add(imm as u32);
                }
            }
            // Branch if Not Equal: 不相等则跳转
            // 功能: 将 rs1 和 rs2 的值进行比较。如果它们不相等，则将 PC 更新为当前 PC + imm。
            // 注意: BNE 的比较不区分符号，因为它只关心比特位是否完全一样。
            Instruction::BNE { rs1, rs2, imm } => {
                if self.get_reg(rs1)? != self.get_reg(rs2)? {
                    next_pc = self.pc.wrapping_add(imm as u32);
                }
            }

            // Branch if Less Than (Signed): 有符号小于则跳转
            // 功能: 将 rs1 和 rs2 的值作为有符号数进行比较。如果 rs1 < rs2，则更新 PC。
            Instruction::BLT { rs1, rs2, imm } => {
                if (self.get_reg(rs1)? as i32) < (self.get_reg(rs2)? as i32) {
                    next_pc = self.pc.wrapping_add(imm as u32);
                }
            }

            // Branch if Greater Than or Equal (Signed): 有符号大于等于则跳转
            // 功能: 将 rs1 和 rs2 的值作为有符号数进行比较。如果 rs1 >= rs2，则更新 PC。
            Instruction::BGE { rs1, rs2, imm } => {
                if (self.get_reg(rs1)? as i32) >= (self.get_reg(rs2)? as i32) {
                    next_pc = self.pc.wrapping_add(imm as u32);
                }
            }

            // Branch if Less Than (Unsigned): 无符号小于则跳转
            // 功能: 将 rs1 和 rs2 的值作为无符号数进行比较。如果 rs1 < rs2，则更新 PC。
            Instruction::BLTU { rs1, rs2, imm } => {
                if self.get_reg(rs1)? < self.get_reg(rs2)? {
                    next_pc = self.pc.wrapping_add(imm as u32);
                }
            }

            // Branch if Greater Than or Equal (Unsigned): 无符号大于等于则跳转
            // 功能: 将 rs1 和 rs2 的值作为无符号数进行比较。如果 rs1 >= rs2，则更新 PC。
            Instruction::BGEU { rs1, rs2, imm } => {
                if self.get_reg(rs1)? >= self.get_reg(rs2)? {
                    next_pc = self.pc.wrapping_add(imm as u32);
                }
            }
            // Jump
            Instruction::JAL { rd, imm } => {
                self.set_reg(rd, self.pc.wrapping_add(4))?;
                next_pc = self.pc.wrapping_add(imm as u32);
            }
            Instruction::JALR { rd, rs1, imm } => {
                let t = self.pc.wrapping_add(4);
                let rs1_val = self.get_reg(rs1)?;
                next_pc = (rs1_val.wrapping_add(imm as u32)) & !1;
                self.set_reg(rd, t)?;
            }

            // System
            Instruction::FENCE { .. } => { /* FENCE is a NOP in our simple simulator */ }
            Instruction::ECALL => {
                // 触发 ECALL 异常
                // 对于 ECALL，mtval 规范要求为 0
                self.trigger_trap(CAUSE_ECALL, 0);
                // 注意：ECALL 后 PC 不会 +4，而是直接跳转到陷阱处理程序
                return Ok(true);
            }
            Instruction::EBREAK => {
                // EBREAK 的行为是停止模拟器，而不是触发陷阱
                return Ok(false); // Stop execution
            }
        }

        self.set_pc(next_pc);
        Ok(true) // Continue execution
    }


    // --- 公共辅助函数 (CPU API) ---

    /// 获取当前程序计数器(PC)的值。
    pub fn get_pc(&self) -> u32 {
        self.pc
    }

    /// 设置程序计数器(PC)的值。
    pub fn set_pc(&mut self, new_pc: u32) {
        self.pc = new_pc;
    }

    /// PC程序计数器的自增。
    /// 默认将PC指向下条指令。
    /// 参数:
    /// - `n`: 自增的步数。
    pub fn pc_inc(&mut self, n: u32) {
        self.pc = self.pc.wrapping_add(n);
    }

    /// 获取指定通用寄存器的值。
    ///
    /// # 参数
    /// * `index`: 寄存器的索引 (0-31)。
    ///
    /// # 返回值
    /// - `Ok(u32)`: 寄存器的值。
    /// - `Err(SimError::InvalidRegister)`: 如果索引超出范围 (>= 32)。
    pub fn get_reg(&self, index: usize) -> Result<u32, SimError> {
        // .get() 方法返回一个 Option，如果索引越界则返回 None
        // .copied() 将 &u32 转换为 u32
        // .ok_or(...) 在 None 的情况下将其转换为我们自定义的错误
        self.regs.get(index).copied().ok_or(SimError::InvalidRegister(index))
    }

    /// 设置指定通用寄存器的值。
    ///
    /// **注意**: 尝试写入 `x0` (索引为0) 会被静默忽略，因为 `x0` 必须永远为0。
    ///
    /// # 参数
    /// * `index`: 寄存器的索引 (0-31)。
    /// * `value`: 要写入的值。
    ///
    /// # 返回值
    /// - `Ok(())`: 如果写入成功。
    /// - `Err(SimError::InvalidRegister)`: 如果索引超出范围 (>= 32)。
    pub fn set_reg(&mut self, index: usize, value: u32) -> Result<(), SimError> {
        if index == 0 {
            return Ok(()); // 关键规则: 对 x0 的写入无效
        }
        if let Some(reg) = self.regs.get_mut(index) {
            *reg = value;
            Ok(())
        } else {
            Err(SimError::InvalidRegister(index))
        }
    }

    /// 获取控制状态寄存器的值。
    ///
    /// # 参数
    /// * `index`: 寄存器的索引 (0-4096)。
    ///
    /// # 返回值
    /// - `Ok(u32)`: 寄存器的值。
    /// - `Err(SimError::InvalidRegister)`: 如果索引超出范围 (>= 4096)。
    pub fn get_csr(&self, index: usize) -> Result<u32, SimError> {
        self.csrs.get(index).copied().ok_or(SimError::InvalidRegister(index))
    }

    /// 设置控制状态寄存器的值。
    ///
    /// # 参数
    /// * `index`: 寄存器的索引 (0-4096)。
    /// * `value`: 要设置的值。
    ///
    /// # 错误
    /// - `SimError::InvalidRegister`: 如果索引超出范围 (>= 4096)。
    pub fn set_csr(&mut self, index: usize, value: u32) -> Result<(), SimError> {
        if index >= 4096 {
            return Err(SimError::InvalidRegister(index));
        }

        if let Some(csr) = self.csrs.get_mut(index) {
            *csr = value;
            Ok(())
        } else {
            Err(SimError::InvalidRegister(index))
        }
    }

    /// 触发一个陷阱（异常或中断）
    /// 这是 CPU 内部处理所有非正常控制流的核心函数。
    fn trigger_trap(&mut self, cause: u32, tval: u32) {
        // 1. 保存当前 PC 到 mepc CSR
        //    注意：我们保存的是当前指令的 PC，而不是 pc + 4
        self.set_csr(CSR_MEPC, self.pc).unwrap(); // 在内部函数中，我们可以 unwrap

        // 2. 记录陷阱原因到 mcause CSR
        self.set_csr(CSR_MCAUSE, cause).unwrap();

        // 3. 记录额外信息到 mtval CSR
        self.set_csr(CSR_MTVAL, tval).unwrap();

        // 4. 读取 mtvec CSR，获取陷阱处理程序的地址
        let trap_handler_addr = self.get_csr(CSR_MTVEC).unwrap();

        // 5. 跳转到陷阱处理程序
        self.set_pc(trap_handler_addr);
    }

    // 在 CPU 模块中的错误处理
    fn handle_memory_error(&mut self, error: SimError, is_store: bool) {
        match error {
            SimError::AddressMisaligned { addr, .. } => {
                let cause = if is_store { 0x6 } else { 0x4 };
                self.trigger_trap(cause, addr);
            }
            SimError::AddressOutOfBounds(addr) => {
                let cause = if is_store { 0x7 } else { 0x5 };
                self.trigger_trap(cause, addr);
            }
            _ => panic!("未处理的内存错误: {:?}", error),
        }
    }

    /// 获取内存实例。
    pub fn get_memory(&self) -> &Memory {
        &self.memory
    }

}


#[cfg(test)]
mod tests {
    use super::*;
    use crate::mem::Memory;
    use std::fs;
    use std::path::Path;

    /// 一个辅助函数，用于在测试中快速创建一个加载了二进制文件的CPU实例。
    fn create_cpu_from_file(path_str: &str) -> Option<Cpu> {
        let path = Path::new(path_str);
        if !path.exists() {
            eprintln!("\n警告：测试文件 '{}' 不存在，跳过相关测试。", path_str);
            return None;
        }

        let mut memory = Memory::new(0x8000_0000, 2 * 1024 * 1024);
        let bin_data = fs::read(path).expect("测试时无法读取BIN文件");
        memory.load_image(0x8000_0000, &bin_data).expect("测试时内存加载失败");
        
        Some(Cpu::new(memory))
    }

    #[test]
    fn test_cpu_initialization() {
        let memory = Memory::new(0x8000_0000, 1024);
        let cpu = Cpu::new(memory);
        
        assert_eq!(cpu.get_pc(), 0x8000_0000);
        assert_eq!(cpu.get_reg(0).unwrap(), 0);
        assert_eq!(cpu.get_reg(31).unwrap(), 0);
    }

    #[test]
    fn test_fetch_instruction() {
        let bin_path = "D:\\Users\\92439\\Documents\\00_ThinkB16P\\04_RiscV\\update-x-bin";
        
        if let Some(cpu) = create_cpu_from_file(bin_path) {
            // 从原始二进制文件中读取前4个字节来确定期望的第一条指令
            let bin_data = fs::read(bin_path).unwrap();
            let expected_instruction = u32::from_le_bytes(
                bin_data[0..4].try_into().expect("测试的bin文件至少应有4字节")
            );

            // 验证 fetch 的结果
            assert_eq!(cpu.fetch().unwrap(), expected_instruction);
            // 验证 fetch 后 PC 没有改变
            assert_eq!(cpu.get_pc(), 0x8000_0000);
        }
    }

    #[test]
    fn test_step_updates_pc() {
        let mut memory = Memory::new(0x8000_0000, 1024); // <-- 设为 mut
        
        // --- 新增：在测试开始前，向内存中写入一条有效的 NOP 指令 ---
        // ADDI x0, x0, 0  => 0x00000513
        let nop_instruction = 0x00000513;
        memory.write_u32(0x8000_0000, nop_instruction).unwrap();
        // -----------------------------------------------------------

        let mut cpu = Cpu::new(memory);
        
        let initial_pc = cpu.get_pc();
        cpu.step().unwrap(); // 现在这里应该会成功
        let pc_after_step = cpu.get_pc();

        assert_eq!(pc_after_step, initial_pc.wrapping_add(4));
    }

    #[test]
    fn test_set_reg_x0_is_ignored() {
        let memory = Memory::new(0x8000_0000, 1024);
        let mut cpu: Cpu = Cpu::new(memory);

        // 尝试向 x0 写入一个非零值
        cpu.set_reg(0, 12345).unwrap();
        // 验证 x0 仍然是 0
        assert_eq!(cpu.get_reg(0).unwrap(), 0);
    }

    #[test]
    fn test_cpu_run() { 
        let bin_path = "D:\\Users\\92439\\Documents\\00_ThinkB16P\\04_RiscV\\update-x-bin";
        
        match create_cpu_from_file(bin_path) {
            Some(mut cpu) => {
                match cpu.run() {
                    Ok(_) => {},
                    Err(e) => panic!("CPU 运行时出错: {:?}", e)
                }
            },
            None => {
                panic!("CPU 运行时出错: creat cpu failed.");
            }
        }
    }

}

